home *** CD-ROM | disk | FTP | other *** search
- _80x86 OPTIMIZATION_
- by Michael Abrash
-
-
- [LISTING ONE]
-
- ; Copies one string to another string, converting all characters to
- ; uppercase in the process, using a loop containing LODSB and STOSB.
- ; Adapted from Zen of Assembly Language, by Michael Abrash; not a
- ; standalone program, but designed to be used with the Zen timer from
- ; that book via the Zen timer's PZTIME.BAT batch file: ZTimerOn starts
- ; the clock, ZTimerOff stops it, and the test-bed program linked in by
- ; PZTIME.BAT starts the program, reports the results, and ends.
-
- jmp Skip ;skip over data in CS and subroutine
-
- SourceString label word ;sample string to copy
- db 'This space intentionally left not blank',0
- DestString db 100 dup (?) ;destination for copy
-
- ; Copies one zero-terminated string to another string,
- ; converting all characters to uppercase.
- ; Input: DS:SI = start of source string; DS:DI = start of destination buffer
- ; Output: none
- ; Registers altered: AX, BX, SI, DI, ES
- ; Direction flag cleared
-
- CopyStringUpper:
- mov ax,ds
- mov es,ax ;for STOS
- mov bl,'a' ;set up for fast register-register
- mov bh,'z' ; comparisons
- cld
- StringUpperLoop:
- lodsb ;get next character and point to following character
- cmp al,bl ;below 'a'?
- jb IsUpper ;yes, not lowercase
- cmp al,bh ;above 'z'?
- ja IsUpper ;yes, not lowercase
- and al,not 20h ;is lowercase-make uppercase
- IsUpper:
- stosb ;put character into new string and point to
- ; following location
- and al,al ;is this the zero that marks end of the string?
- jnz StringUpperLoop ;no, do the next character
- ret
-
- ; Calls CopyStringUpper to copy & convert SourceString->DestString.
- Skip:
- call ZTimerOn ;start timing
- mov si,offset SourceString ;point SI to the string to copy from
- mov di,offset DestString ;point DI to the string to copy to
- call CopyStringUpper ;copy & convert to uppercase
- call ZTimerOff ;stop timing
-
-
- [LISTING TWO]
-
- ; Copies one string to another string, converting all characters to
- ; uppercase in the process, using no string instructions.
- ; Not a standalone program, but designed to be used with the Zen
- ; timer, as described in Listing 1.
-
- jmp Skip ;skip over data in CS and subroutine
-
- SourceString label word ;sample string to copy
- db 'This space intentionally left not blank',0
- DestString db 100 dup (?) ;destination for copy
-
- ; Copies one zero-terminated string to another string,
- ; converting all characters to uppercase.
- ; Input: DS:SI = start of source string; DS:DI = start of destination string
- ; Output: none
- ; Registers altered: AL, BX, SI, DI
-
- CopyStringUpper:
- mov bl,'a' ;set up for fast register-register
- mov bh,'z' ; comparisons
- StringUpperLoop:
- mov al,[si] ;get the next character and
- inc si ; point to the following character
- cmp al,bl ;below 'a'?
- jb IsUpper ;yes, not lowercase
- cmp al,bh ;above 'z'?
- ja IsUpper ;yes, not lowercase
- and al,not 20h ;is lowercase-make uppercase
- IsUpper:
- mov [di],al ;put the character into the new string and
- inc di ; point to the following location
- and al,al ;is this the zero that marks the end of the string?
- jnz StringUpperLoop ;no, do the next character
- ret
-
- ; Calls CopyStringUpper to copy & convert SourceString->DestString.
- Skip:
- call ZTimerOn
- mov si,offset SourceString ;point SI to the string to copy from
- mov di,offset DestString ;point DI to the string to copy to
- call CopyStringUpper ;copy & convert to uppercase
- call ZTimerOff
-
-
- [LISTING THREE]
-
- ; Clears a buffer using MOV/ADD in a loop.
- ; Not a standalone program, but designed to be used with the Zen
- ; timer, as described in Listing 1.
-
- mov dx,2 ;repeat the test code twice, to make
- ; sure it's in the cache (if there is one)
- mov bx,dx ;distance from the start of one word
- ; to the start of the next
- sub ax,ax ;set buffer to zeroes
- TestTwiceLoop:
- mov cx,1024 ;clear 1024 words starting at address
- mov di,8000h ; DS:8000h (this is just unused memory
- ; past the end of the program)
- call ZTimerOn ;start timing (resets timer to 0)
- StoreLoop:
- mov [di],ax ;clear the current word
- add di,bx ;point to the next word
- dec cx ;count off words to clear until none
- jnz StoreLoop ; remain
- call ZTimerOff ;stop timing
- dec dx ;count off passes through test code
- jz StoreDone ;that was the second pass; we're done
- jmp TestTwiceLoop ;that was first pass; do second pass with all
- ; instructions and data in the cache
- StoreDone:
-
-
- [LISTING FOUR]
-
- ; Clears a buffer using MOV/ADD in an unrolled loop.
- ; Not a standalone program, but designed to be used with the Zen
- ; timer, as described in Listing 1.
-
- mov dx,2 ;repeat the test code twice, to make
- ; sure it's in the cache (if there is one)
- mov bx,dx ;distance from the start of one word
- ; to the start of the next
- sub ax,ax ;set buffer to zeroes
- TestTwiceLoop:
- mov si,1024 ;clear 1024 words starting at address
- mov di,8000h ; DS:8000h (this is just unused memory
- ; past the end of the program)
- call ZTimerOn ;start timing (resets timer to 0)
- mov cl,4 ;divide the count of words to clear by
- shr si,cl ; 16, because we'll clear 16 words
- ; each time through the loop
- StoreLoop:
- REPT 16 ;clear 16 words in a row without looping
- mov [di],ax ;clear the current word
- add di,bx ;point to the next word
- ENDM
- dec si ;count off blocks of 16 words to clear
- jnz StoreLoop ; until none remain
- call ZTimerOff ;stop timing
- dec dx ;count off passes through test code
- jz StoreDone ;that was the second pass; we're done
- jmp TestTwiceLoop ;that was the first pass; do the second pass
- ; with all instructions and data in the cache
- StoreDone:
-
-